/*
线程同步
    1.同步方法
        使用synchronized修饰可能被竞争的资源
        public synchronized boolean open() throws InterruptedException{
            do something
        }
    2.同步语句
        使用synchronized修饰可能出现问题的整个对象
        synchronized (testDevice){
            do something about testDevice
        }

 */
public class Project {
    public static void main(String[] args) throws InterruptedException {
        TestDevice testDevice = new TestDevice();
        NewThread thread1 = new NewThread(testDevice, "Hello");
        NewThread thread2 = new NewThread(testDevice, "world");
        NewThread thread3 = new NewThread(testDevice, "java");
        thread1.thread.join();
        thread2.thread.join();
        thread3.thread.join();
        System.out.println("main end");
    }
}

class TestDevice{
    volatile boolean sta = false;
    //如果是自定义的类，可以在有需要的地方定义同步方法
    public synchronized boolean open() throws InterruptedException {
            System.out.println("open successfully");
            Thread.sleep(500);
            System.out.print("[--- ");
            Thread.sleep(500);
            System.out.print(" --- ");
            Thread.sleep(500);
            System.out.println(" ---]");
            return sta;
    }
    void showString(String string) throws InterruptedException {
        System.out.print("["+string);
        Thread.sleep(1000);
        System.out.println("]");
    }
}

class NewThread implements Runnable{
    Thread thread;
    TestDevice testDevice;
    String string;
    NewThread(TestDevice testDevice, String string){
        thread = new Thread(this);
        this.testDevice = testDevice;
        this.string = string;
        thread.start();
    }
    public void run(){
        //同步语句
        //如果是别人给的类，无法访问源码，则将整个实例同步
        synchronized (testDevice){
            try {
                testDevice.open();
                testDevice.showString(string);
            } catch (InterruptedException e) {
                System.out.println(e);
            }
        }

    }

}
